<?php
/**
 * Hoffman Framework
 *
 * LICENSE
 *
 * This source file is subject to the GNU LGPL 2.1 license that is bundled
 * with this package in the file license.txt.
 * It is also available through the world-wide-web at this URL:
 * http://creativecommons.org/licenses/LGPL/2.1
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to annop@thaicyberpoint.com so we can send you a copy immediately.
 *
 * @package    Hoffman
 * @author     Ford AntiTrust
 * @copyright  Copyright (c) 2008 Ford AntiTrust (http://www.thaicyberpoint.com/ford/blog)
 * @since      Version Rv 0.2
 * @license    http://creativecommons.org/licenses/LGPL/2.1
 *             GNU LGPL 2.1
 * @filesource
 */

if (!defined('INDEX'))
    die('No direct script access allowed.');

/**
 * @see Hmf_Translate
 */
require_once 'Hmf/Translate.php';

/**
 * Validate
 *
 * @package     Hoffman
 * @subpackage  Hmf
 * @category    Validate
 * @author      Ford AntiTrust
 * @version     SVN: $Id: Validate.php 166 2010-01-20 14:27:55Z annop.s@gmail.com $
 * @link        http://www.thaicyberpoint.com/ford/blog/hmf
 */

class Hmf_Validate {

    private $result = array();

    private $rules = array();

    private $keywordAlias = array();

    public function addKeywordAlias($keyword, $alias) {

        $this->keywordAlias[$keyword] = $alias;
    }

    public function getKeywordAlias($keyword) {

        if(array_key_exists($keyword, $this->keywordAlias))
            return $this->keywordAlias[$keyword];

        return $keyword;
    }
    /**
     * Result from validated information
     * [keyword] => ['value', 'message', 'bool']
     *
     * @return array
     */
    public function getResults() {

        return $this->result;
    }

    /**
     * Getting the rules
     *
     * @return array
     */
    public function getRules() {

        return $this->rules;
    }

    /**
     * Getting the rule with keyword
     *
     * @param unknown_type $keyword
     * @return array
     */
    public function getRule($keyword) {

        return $this->rules[$keyword];
    }

    /**
     * Adding the rule
     *
     * @param string $keyword
     * @param string $rule
     * @param array $args
     * @param string $userErrorMessage
     * @return Hmf_Validate Provides a fluent interface
     */
    public function addRule($keyword, $rule, array $args = array(), $userErrorMessage = null) {

        $this->rules[$keyword][$rule] = array('args' => $args, 'userErrorMessage' => $userErrorMessage);

        return $this;
    }

    /**
     * Removing the rule
     *
     * @param string $keyword
     * @return Hmf_Validate Provides a fluent interface
     */
    public function removeRule($keyword) {

    	unset($this->rules[$keyword]);

    	return $this;
    }

    /**
     * Checked the value is valid
     *
     * @param mixed $keyword
     * @param mixed $value
     * @return bool
     */
    public function isValid($rule, $keyword, $value) {

        $keywordInfo = $this->getRule($keyword);

        $ruleClass = 'Zend_Validate_' . $rule;

        try {

            Zend_Loader::loadClass($ruleClass);

            $class = new ReflectionClass($ruleClass);
            if ($class->implementsInterface('Zend_Validate_Interface')) {
                if ($class->hasMethod('__construct')) {
                    if(count($keywordInfo[$rule]['args']) > 0) {
                        $object = $class->newInstanceArgs($keywordInfo[$rule]['args']);
                    } else {
                        $object = $class->newInstance();
                    }
                } else {
                    $object = $class->newInstance();
                }

                if ($object->isValid($value)) {
                    $this->result[$keyword][$rule] = true;
                    return true;
                } else {
                    $status['value'] = $value;
                    // value is invalid
                    if (is_null($keywordInfo[$rule]['userErrorMessage'])) {
                        foreach ($object->getMessages() as $message) {
                            $status['message'][] = t($message);
                        }
                    } else {
                        $status['message'][] = t($keywordInfo[$rule]['userErrorMessage']);
                    }
                    $status['bool'] = false;
                    $this->result[$keyword][$rule] = $status;
                    return false;
                }
            }
        } catch (Exception $e) {

            show_error($e->getMessage());
        }
        return false;
    }

    /**
     * Validate the data in array
     *
     * @param array $data, the collection data pairs with keyword and data.
     * @return bool
     */
    public function validate(array $data) {

        $hasError = false;
        foreach (self::getRules() as $keyword => $rules) {
            foreach ($rules as $class => $info) {
                if (!self::isValid($class, $keyword, $data[$keyword]))
                    $hasError = true;
            }
        }

        if($hasError) return false;
        else return true;
    }
}
?>